#!/usr/bin/python

import signal;
import gdb;

total_rx_bytes = 0;
total_rx_packets = 0;
rdtsc = 0;
times = 0;

def tfind_entry(num):
	signal.siginterrupt(signal.SIGINT, True);
	if num < 0:
		tid = gdb.execute("tfind", False, True);
	else:
		tid = gdb.execute("tfind "+str(num), False, True);
	signal.siginterrupt(signal.SIGINT, False);
	if tid.find(", tracepoint ") < 0:
		return -1;
	tid = tid[tid.find(", tracepoint ") + len(", tracepoint "):];
	return int(tid);

def sigalrm_handler(num, e):
	global total_rx_bytes, total_rx_packets;
	global rdtsc, times;

	if total_rx_packets == 0:
		print "pack:", total_rx_packets;
	else:
		print "pack:", total_rx_bytes/total_rx_packets, total_rx_bytes, total_rx_packets;
	total_rx_bytes = 0;
	total_rx_packets = 0;

	if times == 0:
		print 0;
	else:
		print rdtsc/times, rdtsc, times;
	rdtsc = 0;
	times = 0;

	print;

def sigint_handler(num, e):
	global keep_running;

	signal.setitimer(signal.ITIMER_REAL, 0);
	try:
		s = raw_input('Continue? (yes)')
	except:
		s = 'y'
	if s[0:1] == 'n' or s[0:1] == 'N':
		keep_running = 0;
	else:
		signal.setitimer(signal.ITIMER_REAL, 1, 1);

gdb.execute("set pagination off", True, True);
gdb.execute("add-symbol-file /lib/modules/3.0.0-rc6+/kernel/drivers/net/e1000e/e1000e.ko 0xf8235000 -s .note.gnu.build-id 0xf824bb94 -s .devinit.text 0xf824aac4 -s .altinstr_replacement 0xf824ba18 -s .devexit.text 0xf824ba4e -s .init.text 0xf8256000 -s .exit.text 0xf824bb83 -s .rodata 0xf824bbc0 -s .rodata.str1.1 0xf824cc04 -s .rodata.str1.4 0xf824d2a4 -s __bug_table 0xf824e294 -s __param 0xf824e2b8 -s .smp_locks 0xf824e368 -s .parainstructions 0xf824e420 -s .altinstructions 0xf824e440 -s .devinit.rodata 0xf824e520 -s .data 0xf824eb00 -s .devinit.data 0xf824f220 -s .gnu.linkonce.this_module 0xf824f860 -s .bss 0xf824f9b4", True, True);


signal.signal(signal.SIGALRM, sigalrm_handler);
signal.signal(signal.SIGINT, sigint_handler);
signal.siginterrupt(signal.SIGINT, False);

#Make sure this is connect gdbframe or not, if not, gtpframe_pipe = 1
gtpframe_pipe = 0;
if str(gdb.selected_thread()) == "None":
	gtpframe_pipe = 1
	gdb.execute("target tfile /sys/kernel/debug/gtpframe_pipe");

signal.setitimer(signal.ITIMER_REAL, 5, 5);

keep_running = 1;
while keep_running:
	try:
		tfind_done = 0;
		if gtpframe_pipe:
			tid = tfind_entry(0);
			if tid < 0:
				raise gdb.error("tfind");
		else:
			tid = tfind_entry(-1);
			if tid < 0:
				break;
		tfind_done = 1;

		if tid == 1:
			total_rx_bytes += long(gdb.parse_and_eval("total_rx_bytes"));
			total_rx_packets += long(gdb.parse_and_eval("total_rx_packets"));
		elif tid == 2:
			rdtsc += long(gdb.parse_and_eval("$pc_tmp_"+str(gdb.parse_and_eval("$cpu_id"))));
			times += 1;
		else:
			raise gdb.error ("Trace id error.");

	except gdb.error, x:
		#print("Drop one entry because", x);
		pass;
	except gdb.MemoryError, x:
		print("Drop one entry because", x);
	except RuntimeError, x:
		print("Drop one entry because", x);

	if gtpframe_pipe and tfind_done:
		gdb.execute("tfind", False, True);
